Fix Rule 14.3 detection for bounded expressions - #8819
Conversation
a1c4a25 to
8dc01be
Compare
8dc01be to
d37f6b1
Compare
| " if ((((sint64)((uint32)tmp)) - 1LL) < 0LL) {}\n" | ||
| " if ((((sint64)((uint32)tmp)) - 1LL) > 4294967295LL) {}\n" | ||
| "}\n", settingsUnix64); | ||
| ASSERT_EQUALS("[test.cpp:9:43]: (style) Comparing expression of type 'signed long long' against value 4294967295. Condition is always false. [compareValueOutOfTypeRangeError]\n", |
There was a problem hiding this comment.
The text/ID of the warning seems incorrect. 4294967295 is within range for signed long long.
There was a problem hiding this comment.
Hello! The condition is essentially (sint64), the diagnostic log is correct. But the check is only possible because there is a (uint32) inside.
|
I have created this ticket: https://trac.cppcheck.net/ticket/15000 |
|
I will update the commit message with Fix #15000 ... |
…ded cast/arithmetic expressions
d37f6b1 to
3e3fa63
Compare
| return false; | ||
|
|
||
| std::uint8_t bits = 0; | ||
| switch (tok->valueType()->type) { |
There was a problem hiding this comment.
maybe this switch could be simplified to something like
if (tok->valueType()->isIntegral())
bits = settings.platform.char_bit *
tok->valueType()->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointee);
I think it would be shorter, duplicate less logic, and it would also support wchar_t
the check for isIntegral() could even be moved up to line 1980 to be very clear that this function only works for integral types
Cheers!
--Aaron
| lower = -(MathLib::bigint(1) << (bits - 1)); | ||
| upper = max / 2; | ||
| } | ||
| } else { |
There was a problem hiding this comment.
enum Sign : std::uint8_t { UNKNOWN_SIGN, SIGNED, UNSIGNED } sign = UNKNOWN_SIGN;
I think if the sign is unknown you should probably return false, not treat it the same as an UNSIGNED
There was missing detection of 'MISRA C:2012 Rule 14.3" on some specific code structure generated by Matlab Simulink coder.
We identified these issues by comparing its results with reports previously generated by our company’s internal tool on the same software.
The bug report would have looked like below.
Problem
Cppcheck did not report a MISRA C:2012 Rule 14.3 violation when a comparison
used an integer expression whose range was provably bounded by casts and
constant arithmetic. The existing check handled a variable compared with a
value outside the variable's declared type range, but did not evaluate this
equivalent expression form.
Minimal Reproducer
After the clamp and casts, the left-hand expression cannot exceed
UINT32_MAX - 1. Therefore the final condition is always false and shouldproduce the
compareValueOutOfTypeRangeErrordiagnostic, which the MISRApostprocessor maps to Rule 14.3.
Observed Behavior
Before the fix, the final comparison produced no diagnostic. This allowed the
generated-code pattern to pass through the cppcheck-based MISRA pipeline
without the expected Rule 14.3 finding.
Fix
The condition checker now:
or subtraction by constant expressions;
provably always true or always false; and
compareValueOutOfTypeRangeErrordiagnostic path.Uncertain or unsupported ranges remain unreported to avoid speculative
findings. Interval arithmetic includes overflow guards.
Regression Coverage
The exact typedef-based reproducer is covered by
TestCondition::compareOutOfTypeRangeintest/testcondition.cpp. The focusedtest, the complete
TestConditionsuite, and the registered CTest target passwith the fix.